package com.example.demo.verify.validator;

import com.example.demo.verify.XssValid;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class XssValidValidator implements ConstraintValidator<XssValid, Object> {
    private boolean empty;

    @Override
    public void initialize(XssValid param) {
        this.empty = param.empty();
    }

    @Override
    public boolean isValid(Object obj, ConstraintValidatorContext context) {
        // 允许字段为空，在非空时才校验
        if (this.empty) {
            if (obj == null) {
                return false;
            }
            if (obj.toString().trim().isEmpty()) {
                return true;
            }
        }
        else {
            // 不能为null或为空
            if (obj == null || obj.toString().trim().isEmpty()) {
                return false;
            }
        }

        String temp = obj.toString().trim();
        String result = cleanXSS(cleanSQLInject(obj.toString().trim()));
        if (!result.equals(temp)) {
            return false;
        }

        return true;
    }

    private String cleanXSS(String src) {
        src = src.replaceAll("<", "＜").replaceAll(">", "＞");
        src = src.replaceAll("\\(", "（").replaceAll("\\)", "）");
        src = src.replaceAll("'", "＇");
        src = src.replaceAll(";", "；");

        src = src.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
        src = src.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41");
        src = src.replaceAll("eval\\((.*)\\)", "");
        src = src.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
        src = src.replaceAll("script", "");
        src = src.replaceAll("link", "");
        src = src.replaceAll("frame", "");

        Pattern pattern = Pattern.compile("(eval\\((.*)\\)|script)", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(src);
        src = matcher.replaceAll("");

        pattern = Pattern.compile("[\\\"\\'][\\s]*javascript:(.*)[\\\"\\']", Pattern.CASE_INSENSITIVE);
        matcher = pattern.matcher(src);
        src = matcher.replaceAll("\"\"");

        // 增加脚本
        src = src.replaceAll("script", "").replaceAll(";", "").replaceAll("0x0d", "").replaceAll("0x0a", "");

        return src;
    }

    private String cleanSQLInject(String src) {
        String lowSrc = src.toLowerCase();
        String lowSrcAfter = lowSrc.replaceAll("insert", "forbidI")
                .replaceAll("select", "forbidS")
                .replaceAll("update", "forbidU")
                .replaceAll("delete", "forbidD").replaceAll("and", "forbidA")
                .replaceAll("or", "forbidO");

        return lowSrcAfter;
    }
}
